package com.wits.qso.web.controller;

import java.io.File;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;
import java.util.UUID;

import javax.servlet.http.HttpSession;

import net.sf.json.JSONArray;

import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.wits.platform.common.constants.UserType;
import com.wits.platform.common.constants.WebConstants;
import com.wits.platform.common.utils.DateUtil;
import com.wits.platform.common.utils.FileUtil;
import com.wits.platform.web.controller.BaseController;
import com.wits.qso.common.enumerate.BusinessType;
import com.wits.qso.entity.Aid;
import com.wits.qso.entity.Attachment;
import com.wits.qso.entity.Btable;
import com.wits.qso.entity.CreContent;
import com.wits.qso.entity.HomeworkH;
import com.wits.qso.entity.MaterialD;
import com.wits.qso.entity.Teacher;
import com.wits.qso.entity.Year;
import com.wits.qso.service.AidService;
import com.wits.qso.service.AttachmentService;
import com.wits.qso.service.BtableDaoService;
import com.wits.qso.service.CreContentService;
import com.wits.qso.service.HomeworkHService;
import com.wits.qso.service.MaterialdService;
import com.wits.qso.service.TeacherService;
import com.wits.qso.service.YearService;

@Controller
@RequestMapping(value = "qso/btable/manage")
public class BtableManageController extends BaseController
{
	protected static final Logger logger = LoggerFactory.getLogger( BtableManageController.class );
	private static final String ATTRIBUTE_AID_UPLOAD_FILES = "aidUploadFiles";
	private static final String ATTRIBUTE_HOMEWORK_UPLOAD_FILES = "homeworkUploadFiles";
	@Autowired
	private AidService aidService = null;
	@Autowired
	private AttachmentService attachmentService = null;
	@Autowired
	private BtableDaoService btableDaoService = null;
	@Autowired
	private CreContentService creContentService = null;
	@Autowired
	private HomeworkHService homeworkHService = null;
	@Autowired
	private MaterialdService materialdService = null;
	@Autowired
	private YearService yearService = null;
	@Autowired
	private TeacherService teacherService = null;

	@RequestMapping(value = "/toList")
	public String toList(Model model) {
		model.addAttribute( "teacherName", getCurrentUser().getName() );
		model.addAttribute( "currentWeek", getCurrentWeeksOfYear() );
		model.addAttribute( "totalWeeks", getWeeksOfThisYear() );
		model.addAttribute( "eventDataJson", btableDaoService.getEventsJson( teacherService.findByUserId( getCurrentUser().getId() ) ) );
		return "qso/btableManage/list";
	}
	
	@RequestMapping(value="/listjson")
	@ResponseBody
	public JSONArray toListJson(Model model){
		String listStr=btableDaoService.getEventsJson( teacherService.findByUserId( getCurrentUser().getId() ) ) ;
		return JSONArray.fromObject(listStr);
	}
	
	@RequestMapping(value = "/view/{viewType}")
	public String toView(Model model, @PathVariable String viewType, @RequestParam String id) {
		Btable btable = null;

		if (StringUtils.isNotBlank( id )) {
			if (UserType.TEACHER.getValue().equals( getCurrentUser().getUserType() )) {
				Teacher teacher = teacherService.findByUserId( getCurrentUser().getId() );
				btable = btableDaoService.findByIdAndTeacher( id, teacher );

				logger.info( "{}", btable );

				CreContent creContent = creContentService.findCreContentByBtable( btable );

				if (null != creContent) {
					model.addAttribute( "aim", creContent.getAim() );
					model.addAttribute( "keynote", creContent.getKeynote() );
					model.addAttribute( "aidId", creContent.getAidId().getId() );
					model.addAttribute( "aidIntro", creContent.getAidId().getIntro() );
					model.addAttribute( "hwkhId", creContent.getHwkhId().getId() );
					model.addAttribute( "hwkh", creContent.getHwkhId().getFile() );

					List<MaterialD> materialDs = creContentService.findMaterialDByBtable( btable );
					StringBuilder mtrdIds = new StringBuilder();
					for (MaterialD materialD : materialDs) {
						mtrdIds.append( materialD.getId() ).append( ";" );
					}
					model.addAttribute( "materialdValue", mtrdIds.toString() );
				}

				model.addAttribute( "materialdList", materialdService.findByCourse( btable.getCouid() ) );
				model.addAttribute( WebConstants.COMMAND, btable );
			}
		}

		model.addAttribute( "viewType", viewType );

		return "qso/btableManage/form";
	}

	@RequestMapping(value = "/save", method = RequestMethod.POST)
	@ResponseBody
	public Object save(@RequestParam(value = "btableId") String id, @RequestParam(value = "aidId") String aidId, @RequestParam(value = "hwkhId") String hwkhId,
	        @RequestParam(value = "aim") String aim, @RequestParam(value = "keynote") String keynote, @RequestParam(value = "aidIntro") String aidIntro,
	        @RequestParam(value = "materialdValue") String materialdValue, @RequestParam(value = "hwkh") String hwkh, HttpSession session) {

		if (StringUtils.isBlank( id )) {
			return ajaxDoneError( this.getText( "save.failed" ) );
		} else {
			if (UserType.TEACHER.getValue().equals( getCurrentUser().getUserType() )) {
				Teacher teacher = teacherService.findByUserId( getCurrentUser().getId() );
				Btable btable = btableDaoService.findByIdAndTeacher( id, teacher );

				creContentService.deleteByBtable( btable );

				Aid aid = null;
				if (StringUtils.isNotBlank( aidId )) {
					aid = aidService.getOne( aidId );
					aid.setDateUpd( DateUtil.getNow() );
					aid.setUserUpd( getCurrentUserId() );
				} else {
					aid = new Aid();
					aid.setDateCre( DateUtil.getNow() );
					aid.setUserCre( getCurrentUserId() );
					aid.setShare( "0" );
					aid.setTeaid( teacher );
					aid.setName( aidIntro );
				}

				aid.setIntro( aidIntro );
				aid = aidService.save( aid );

				HomeworkH homeworkH = null;
				if (StringUtils.isNotBlank( hwkhId )) {
					homeworkH = homeworkHService.getOne( hwkhId );
					homeworkH.setDateUpd( DateUtil.getNow() );
					homeworkH.setUserUpd( getCurrentUserId() );
				} else {
					homeworkH = new HomeworkH();
					homeworkH.setDateCre( DateUtil.getNow() );
					homeworkH.setUserCre( getCurrentUserId() );
				}

				homeworkH.setTitle( hwkh );
				homeworkH = homeworkHService.save( homeworkH );

				List<String> aidUploadFiles = (List<String>) session.getAttribute( ATTRIBUTE_AID_UPLOAD_FILES );
				List<String> homeworkUploadFiles = (List<String>) session.getAttribute( ATTRIBUTE_HOMEWORK_UPLOAD_FILES );

				if (null != aidUploadFiles) {
					// save aid's attachment
					for (String aidUploadFile : aidUploadFiles) {
						Attachment attachment = attachmentService.getOne( aidUploadFile );
						attachment.setBusinessId( aid.getId() );
						attachmentService.save( attachment );
					}

					session.removeAttribute( ATTRIBUTE_AID_UPLOAD_FILES );
				}

				if (null != homeworkUploadFiles) {
					// save homeworkh's attachment
					for (String homeworkUploadFile : homeworkUploadFiles) {
						Attachment attachment = attachmentService.getOne( homeworkUploadFile );
						attachment.setBusinessId( homeworkH.getId() );
						attachmentService.save( attachment );
					}

					session.removeAttribute( ATTRIBUTE_HOMEWORK_UPLOAD_FILES );
				}

				try {
					for (String materialdId : materialdValue.split( ";" )) {
						if (StringUtils.isNotBlank( materialdId )) {
							CreContent creContent = new CreContent();
							creContent.setAim( aim );
							creContent.setKeynote( keynote );
							creContent.setMtrdId( materialdService.getOne( materialdId ) );
							creContent.setBtId( btable );
							creContent.setAidId( aid );
							creContent.setHwkhId( homeworkH );

							creContentService.save( creContent );
						}
					}
				} catch (Throwable cause) {
					logger.error( cause.getMessage(), cause );
				}
			}
		}

		return ajaxDoneSuccess( this.getText( "save.success" ) );
	}

	@RequestMapping(value = "/aid/upload")
	public void aidUpload(@RequestParam(value = "attachment") MultipartFile multipartFile, HttpSession session) {
		if (null != multipartFile) {
			// logger.info( "{}, {}", multipartFile.getSize(), multipartFile.getOriginalFilename() );

			List<String> uploadFiles = (List<String>) session.getAttribute( ATTRIBUTE_AID_UPLOAD_FILES );
			if (null == uploadFiles) {
				uploadFiles = new ArrayList<String>();
			}

			String uuid = UUID.randomUUID().toString().replace( "-", "" );
			Attachment attachment = new Attachment();
			// attachment.setId( UUID.randomUUID().toString() );
			attachment.setBusinessType( BusinessType.AID.getValue() );
			attachment.setDateCre( DateUtil.getNow() );
			attachment.setFileSize( multipartFile.getSize() );
			attachment.setOriginalName( multipartFile.getOriginalFilename() );
			attachment.setExtName( FilenameUtils.getExtension( multipartFile.getOriginalFilename() ) );

			String storagePath = WebConstants.UPLOAD_DIR + File.separator + BusinessType.AID.getValue() + File.separator + uuid;

			attachment.setFilePath( storagePath + File.separator + uuid + "." + attachment.getExtName() );
			attachment = attachmentService.save( attachment );
			try {
				FileUtil.upload( multipartFile, session.getServletContext().getRealPath( "/" ) + storagePath, uuid + "." + attachment.getExtName() );

				uploadFiles.add( attachment.getId() );
				session.setAttribute( ATTRIBUTE_AID_UPLOAD_FILES, uploadFiles );
			} catch (Throwable cause) {
				logger.error( cause.getMessage(), cause );
			}
		}
	}

	@RequestMapping(value = "/homework/upload")
	public void homeworkUpload(@RequestParam(value = "attachment") MultipartFile multipartFile, HttpSession session) {
		if (null != multipartFile) {
			// logger.info( "{}, {}", multipartFile.getSize(), multipartFile.getOriginalFilename() );

			List<String> uploadFiles = (List<String>) session.getAttribute( ATTRIBUTE_HOMEWORK_UPLOAD_FILES );
			if (null == uploadFiles) {
				uploadFiles = new ArrayList<String>();
			}

			String uuid = UUID.randomUUID().toString().replace( "-", "" );
			Attachment attachment = new Attachment();
			attachment.setBusinessType( BusinessType.HWKH.getValue() );
			attachment.setDateCre( DateUtil.getNow() );
			attachment.setFileSize( multipartFile.getSize() );
			attachment.setOriginalName( multipartFile.getOriginalFilename() );
			attachment.setExtName( FilenameUtils.getExtension( multipartFile.getOriginalFilename() ) );

			String storagePath = WebConstants.UPLOAD_DIR + File.separator + BusinessType.HWKH.getValue() + File.separator + uuid;

			attachment.setFilePath( storagePath + File.separator + uuid + "." + attachment.getExtName() );
			attachment = attachmentService.save( attachment );
			try {
				FileUtil.upload( multipartFile, session.getServletContext().getRealPath( "/" ) + storagePath, uuid + "." + attachment.getExtName() );

				uploadFiles.add( attachment.getId() );
				session.setAttribute( ATTRIBUTE_HOMEWORK_UPLOAD_FILES, uploadFiles );
			} catch (Throwable cause) {
				logger.error( cause.getMessage(), cause );
			}
		}
	}

	protected int getCurrentWeeksOfYear() {
		int weeks = 1;
		Year year = yearService.findEnabled();

		if (null != year) {
			Calendar current = Calendar.getInstance();
			current.set( Calendar.HOUR_OF_DAY, 0 );
			current.set( Calendar.MINUTE, 0 );
			current.set( Calendar.SECOND, 0 );
			current.set( Calendar.MILLISECOND, 0 );

			Calendar start = Calendar.getInstance();
			start.setTime( year.getDateF() );

			long diff = current.getTimeInMillis() - start.getTimeInMillis();
			int dayCount = new Float( (float) diff / (24 * 60 * 60 * 1000) ).intValue();

			weeks = dayCount / 7 + (0 != (dayCount % 7) ? 1 : 0);
		}

		return weeks;
	}

	protected int getWeeksOfThisYear() {
		Year year = yearService.findEnabled();
		int weeks = 1;

		if (null != year) {
			Calendar start = Calendar.getInstance();
			Calendar end = Calendar.getInstance();
			start.clear();
			end.clear();

			start.setTime( year.getDateF() );
			end.setTime( year.getDateT() );

			long diff = end.getTimeInMillis() - start.getTimeInMillis();

			int dayCount = new Float( (float) diff / (24 * 60 * 60 * 1000) ).intValue();

			weeks = dayCount / 7 + (0 != (dayCount % 7) ? 1 : 0);
		}

		return weeks;
	}
}
